import CoordinateService from "../utils/coordinate.js";
import $ from "jquery";
import * as DrawUtil from "../utils/link/index.js";
import EdgeClass from "./edge/EdgeClass.js";
function _detectMob() {
  const toMatch = [
    /Android/i,
    /webOS/i,
    /iPhone/i,
    /iPad/i,
    /iPod/i,
    /BlackBerry/i,
    /Windows Phone/i,
    /Electron/i,
  ];
  return toMatch.some((toMatchItem) => {
    return window.navigator.userAgent.match(toMatchItem);
  });
}
let _detectZoom = () => {
  let ratio = 0;
  let screen = window.screen;
  let ua = window.navigator.userAgent.toLowerCase();

  if (window.devicePixelRatio !== undefined) {
    ratio = window.devicePixelRatio;
  } else if (~ua.indexOf("msie")) {
    if (screen.deviceXDPI && screen.logicalXDPI) {
      ratio = screen.deviceXDPI / screen.logicalXDPI;
    }
  } else if (
    window.outerWidth !== undefined &&
    window.innerWidth !== undefined
  ) {
    ratio = window.outerWidth / window.innerWidth;
  }

  if (ratio) {
    ratio = Math.round(ratio * 100);
  }
  return ratio;
};
export class ScheduleManager {
  constructor(rootView) {
    this.rootView = rootView;
    this.root = null;
    this.svg = null;
    this.inited = false;
    this._zoomData = 1;
    this._moveData = [0, 0];
    this._nodeMap = new Map();
    this._nodes = [];
    this._edges = [];
    this._edgesMap = new Map();
  }
  init(root, svg) {
    this.inited = true;
    this.root = root;
    this.svg = svg;
    this._genSvgWrapper();
    // 初始化一些参数
    this._rootWidth = $(this.root).width();
    this._rootHeight = $(this.root).height();
    $(this.root).css("overflow", "hidden");
    if ($(this.root).css("position") === "static") {
      $(this.root).css("position", "relative");
    }
    this._coordinateService = new CoordinateService({
      canvas: this,
      terOffsetX: $(this.root).offset().left,
      terOffsetY: $(this.root).offset().top,
      terWidth: $(this.root).width(),
      terHeight: $(this.root).height(),
      canOffsetX: this._moveData[0],
      canOffsetY: this._moveData[1],
      scale: this._zoomData,
    });
  }
  _genSvgWrapper() {
    let _isMobi = _detectMob();
    let _SVGWidth = "100%";
    let _SVGHeight = "100%";

    // hack 适配浏览器的缩放比例
    if (!_isMobi) {
      let _scale = 1 / (_detectZoom() / 200);
      _SVGWidth = 1 * _scale + "px";
      _SVGHeight = 1 * _scale + "px";
    }

    // 生成svg的wrapper
    const svg = $(this.svg)
      .attr("width", _SVGWidth)
      .attr("height", _SVGHeight)
      .attr("version", "1.1")
      .attr("xmlns", "http://www.w3.org/2000/svg")
      .css("z-index", 499);

    if (!_isMobi) {
      // hack 监听浏览器的缩放比例并适配
      window.onresize = () => {
        let _scale = 1 / (_detectZoom() / 200);
        svg.attr("width", 1 * _scale + "px").attr("height", 1 * _scale + "px");
      };

      // hack 因为width和height为1的时候会有偏移
      let wrapperOffset = $(this.root)[0].getBoundingClientRect();
      let svgOffset = svg[0].getBoundingClientRect();
      svg
        .css("top", wrapperOffset.top - svgOffset.top + "px")
        .css("left", wrapperOffset.left - svgOffset.left + "px");
    }
  }
  drawEdge() {
    $(this.svg).empty();
    const _edgeFragment = document.createDocumentFragment();
    this._nodes.forEach((item) => {
      let edge = this.addNodeLine(item);
      if (edge) {
        _edgeFragment.appendChild(edge.dom);
        this._edges.push(edge);
        edge.mounted && edge.mounted();
      }
    });
    $(this.svg).append(_edgeFragment);
    this._edges.forEach((link) => {
      link.redraw();
    });
  }
  addNodeLine(node) {
    let parentNode = this._nodeMap.get(node.pid);
    let { rightDot: sourcePoint } = parentNode?.$refs || {};
    let { leftDot: targetPoint } = node.$refs;
    if (!sourcePoint) {
      if (targetPoint) {
        $(targetPoint).hide();
      }
      return;
    }
    if (node && parentNode && sourcePoint && targetPoint) {
      $(sourcePoint).show();
      $(targetPoint).show();
      let edge = new EdgeClass({
        type: "endpoint",
        id: `source_${parentNode.id}:target_${node.id}`,
        // defaultAnimate: this.theme.edge.defaultAnimate,
        sourceNode: parentNode,
        targetNode: node,
        sourceEndpoint: sourcePoint,
        targetEndpoint: targetPoint,
      });
      edge._init({
        _coordinateService: this._coordinateService,
      });
      return edge;
    }
  }

  addViewNode(node) {
    let oldNode = this._nodeMap.get(node.id);
    if (oldNode) {
      this.removeViewNode(node);
    }
    this._nodes.push(node);
    this._nodeMap.set(node.id, node);
    if (this.inited) {
      let edge = this.addNodeLine(node);
      if (edge) {
        let oldIndex = this._edges.findIndex((item) => item.id === edge.id);
        if (oldIndex > -1) {
          let oldEdges = this._edges.splice(oldIndex, 1);
          oldEdges.forEach((item) => {
            item.destroy();
          });
        }
        this._edges.push(edge);
        edge.mounted && edge.mounted();
        $(this.svg).append(edge.dom);
        edge.redraw();
      }
    }
  }
  removeViewNode(node) {
    if (this.inited) {
      this.removeNodeLine(node);
    }
    let n = this._nodeMap.get(node.id);
    if (n === node) {
      this._nodeMap.delete(node.id);
    }
    let index = this._nodes.findIndex((item) => item === node);
    if (index > -1) {
      this._nodes.splice(index, 1);
    }
  }
  getNodeById(id) {
    return this._nodeMap.get(id);
  }
  // getChildrenNodes(id) {
  //   let children = [];
  //   let node = this.getNodeById(id);
  //   this._edges = this._edges.filter((item) => {
  //     if (item.sourceNode === node) {
  //       children.push(item.targetNode);
  //     }
  //   });
  //   return children;
  // }
  getPatientNodeById(id) {
    let node = this.getNodeById(id);
    let parentNode = node && this._nodeMap.get(node.pid);
    return parentNode || null;
  }
  removeNodeLine(node) {
    if (!node) {
      return;
    }
    let prevEdges = [];
    let nextEdges = [];

    this._edges = this._edges.filter((item) => {
      let isDel = false;
      if (item.sourceNode === node) {
        nextEdges.push(item);
        isDel = true;
      } else if (item.targetNode === node) {
        prevEdges.push(item);
        isDel = true;
      }
      return !isDel;
    });

    [...prevEdges, ...nextEdges].forEach((item) => {
      item.destroy();
    });
  }
  updateHighlight(id) {
    let ids = Array.isArray(id) ? id : [id];
    ids.forEach((item) => {
      let node = this._nodeMap.get(item);
      let prevEdges = [];
      let nextEdges = [];
      this._edges.forEach((item) => {
        if (item.sourceNode === node) {
          nextEdges.push(item);
        } else if (item.targetNode === node) {
          prevEdges.push(item);
        }
      });
      [...prevEdges, ...nextEdges].forEach((item) => {
        let hasHighlight = item.updateHighlight();
        hasHighlight && $(this.svg).append(item.dom);
      });
    });
  }
  updateEdges() {
    console.log("xxxx");
    this._edges.forEach((link) => {
      link.redraw();
    });
  }
}
